package cn.redragon.soa.amqp.handler;

import cn.redragon.soa.amqp.model.StockImportedEvent;
import cn.redragon.soa.amqp.model.StockUpdatedEvent;
import cn.redragon.soa.common.amqp.ReplyToListener;
import cn.redragon.soa.common.constant.Constants;
import cn.redragon.soa.common.constant.Constants.MQ;
import cn.redragon.soa.common.enums.StockActionType;
import cn.redragon.soa.common.enums.StockImportMode;
import cn.redragon.soa.common.util.JsonUtil;
import cn.redragon.soa.service.StockHistoryService;
import cn.redragon.soa.service.StockService;
import javax.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.rabbit.annotation.Argument;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@RequiredArgsConstructor
public class StockEventListener extends ReplyToListener {

    private final StockService stockService;
    private final StockHistoryService stockHistoryService;

    @RabbitListener(containerFactory = "containerFactory",
        bindings = {
            @QueueBinding(
                value = @Queue(
                    name = "${amqp.oms.inbound.stock.imported.queueName}", durable = "true", autoDelete = "false",
                    arguments = {
                        @Argument(name = "x-dead-letter-exchange"),
                        @Argument(name = "x-dead-letter-routing-key", value = "${amqp.oms.inbound.stock.imported.dlqName}")
                    }),
                exchange = @Exchange(value = "${amqp.oms.inbound.exchangeName}", type = ExchangeTypes.TOPIC),
                key = "${amqp.oms.inbound.stock.imported.routingKey}"
            )
        },
        exclusive = true,
        autoStartup = "true",
        errorHandler = "listenerErrorHandler"
    )
    public void processStockImportedEvent(@Header(name = MQ.APP) String appCode, @Payload @Valid StockImportedEvent event) {
        log.info("Received StockImportedEvent: {}.", JsonUtil.objectToJsonStr(event));
        stockService.importStocks(appCode, event, StockActionType.IMPORT, StockActionType.IMPORT.name(), StockImportMode.FULL);
    }

    @RabbitListener(containerFactory = "containerFactory",
        bindings = {
            @QueueBinding(
                value = @Queue(
                    name = "${amqp.inner.stock.updated.queueName}", durable = "true", autoDelete = "false",
                    arguments = {
                        @Argument(name = "x-dead-letter-exchange"),
                        @Argument(name = "x-dead-letter-routing-key", value = "${amqp.inner.stock.updated.dlqName}")
                    }),
                exchange = @Exchange(value = "${amqp.inner.exchangeName}", type = ExchangeTypes.TOPIC),
                key = "${amqp.inner.stock.updated.routingKey}"
            )
        },
        autoStartup = "true",
        errorHandler = "listenerErrorHandler"
    )
    public void processStockHistoryUpdatedEvent(@Header(name = Constants.MQ.APP) String appCode, @Payload @Valid StockUpdatedEvent event) {
        log.info("Received StockUpdatedEvent: {}.", JsonUtil.objectToJsonStr(event));
        stockHistoryService.save(appCode, event.getHistories());
    }
}
